﻿var fieldsList = [];
var selectPropertyDropDownHtml = "";
var camlValidationFailed = false;
var multipleValueSeparator = "<AND>";
var excludedLookupFields = ["AppAuthor", "AppEditor", "SyncClientId", "Created_x0020_Date", "FolderChildCount", "ItemChildCount", "Last_x0020_Modified", "FileDirRef", "ProgId", "MetaInfo", "ScopeId", "SortBehavior", "UniqueId", "FileRef"];

$(document).ready(function () {
    hideTab("tabCamlGenerator");
    LoadSharePointRuntime();
});

function LoadSharePointRuntime() {
    var siteUrl = $("#txtRootWebUrl").val();
    console.log("Loading sharepoint runtime");
    var scriptbase = siteUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.Runtime.js",
        function () {
            console.log("loaded SP.Runtime.js");
            $.getScript(scriptbase + "SP.js",
                    function () {
                        spRuntimeLoaded = true;
                        console.log("loaded SP.js");
                    }
            );
        });
}

function SetCAMLTabHeight() {
    //console.log("SetCAMLTabHeight");
    //$("#tabCamlQueryDiv").height(50);

    //var mainDivHeight = $('#SPEmain')[0].scrollHeight;
    //var mainFooter = $("#SPEfooter")[0].scrollHeight;
    //var requestInfoHeight = $("#oDataRequestInfo")[0].scrollHeight;
    //var tabResultsHeight = $("#tabResults")[0].scrollHeight;
    //var tabPropertiesHeight = $("#tabProperties")[0].scrollHeight;
    //var tabCamlGenerator = $("#tabCamlGenerator")[0].scrollHeight;

    //var divCamlBuilderTabsHeight = $("#divCamlBuilderTabs")[0].scrollHeight
    //var tabsResultsHeight = $("#tabsResults")[0].scrollHeight

    //var tabCamlGeneratorHeight = $("#tabCamlGenerator")[0].scrollHeight;
    //var tabCamlQueryHeight = $("#tabCamlQuery")[0].scrollHeight;


    ////38 is the height of div
    //$("#tabCamlQueryDiv").height(mainDivHeight - mainFooter - requestInfoHeight - tabsResultsHeight - 38 - 24);

    //var tabCamlQuerySelectFieldsHeader = $("#tabCamlQuerySelectFieldsHeader").height();
    //console.log("height() : " +tabCamlQuerySelectFieldsHeader);
    //var tabCamlQuerySelectFieldsHeader = $("#tabCamlQuerySelectFieldsHeader")[0].scrollHeight;
    //console.log("scrollHeight : " + tabCamlQuerySelectFieldsHeader);
    //var tabCamlQuerySelectFieldsDivHeight = $("#tabCamlQuerySelectFieldsDiv").height();
    //console.log(tabCamlQuerySelectFieldsDivHeight);
    //$("#tabCamlQuerySelectFieldsListDiv").height(tabCamlQuerySelectFieldsDivHeight -tabCamlQuerySelectFieldsHeader);
}

function ShowCamlBuilderTab() {
    ShowProgress();
    //$('.selectpicker').selectpicker();

    var spListTitle = $("#spListTitle").text();
    var spListId = $("#spListId").text();
    var spOdataUrl = $("#spOdataUrl").text();
    var spListOdataUrl = $("#spListOdataUrl").text();

    var spListFieldsOdataUrl = spListOdataUrl + "/Fields?$orderby=Title";
    if (spOdataUrl.indexOf("/Items?@target=") > -1) {
        spListFieldsOdataUrl = StringReplaceIgnoreCase(spOdataUrl, "/Items", "/Fields");
        spListFieldsOdataUrl = StringReplaceIgnoreCase(spListFieldsOdataUrl, "@target=", "$orderby=Title&@target=");
    }

    $("#spListFieldsOdataUrl").text(spListFieldsOdataUrl);

    showTab("tabCamlGenerator");

    PopulateFields(spListFieldsOdataUrl);

    InitCamlBuilder();

    $("#camlBuilderDialogTitle").html("CAML Builder: " + spListTitle);
}

function showTab(tab) {
    $('.nav-tabs a[href="#' +tab + '"]').attr("style", "display:block");
    $('.nav-tabs a[href="#' + tab + '"]').tab('show');
};
function hideTab(tab) {
    $('.nav-tabs a[href="#' +tab + '"]').attr("style", "display:none");
};

function GetChildNodeCount(parentObject) {
    var childCount = $(parentObject).parent().parent().parent().find("> ul").length;
    return childCount;
}

function GetSiblingNodeCount(parentObject) {
    var childCount = $(parentObject).parent().parent().parent().parent().find("> ul").length;
    return childCount;
}

function IsRootNode(parentObject) {
    var jsTreeCamlId = $(parentObject).parent().parent().parent().parent().attr("id");
    if (jsTreeCamlId === "jsTreeCaml") {
        return true;
    }
    else {
        return false;
    }
}

function ddlOperator_onchange(ddlOperator) {
    var selectedOperatorValue = $(ddlOperator).val();
    var parentObject = $(ddlOperator).parent().parent();

    var camlOperatorValueTemplate = parentObject.find("div[id^='camlOperatorValueTemplate']");

    var ddlSelectCAMLProperty = parentObject.find("select[id^='ddlSelectCAMLProperty']");
    var selectedValueObject = $("#" + ddlSelectCAMLProperty[0].id + ">option:selected")

    var typeAsString = selectedValueObject.attr("typeasstring");
    var allowMultipleValues = selectedValueObject.attr("AllowMultipleValues");
    var schemaXml = selectedValueObject.attr("schemaXml");

    var objTxtPropertyValue = parentObject.find("input[id^='txtPropertyValue']");
    var objChkUseId = parentObject.find("input[id^='chkUseId']");
    var objLblUseId = parentObject.find("label[id^='lblUseId']");
    var objBtnSelectValue = parentObject.find("button[id^='btnSelectValue']");

    if (selectedOperatorValue) {
        var fieldInternalName = ddlSelectCAMLProperty.val();
        //if (selectedOperatorValue === "BeginsWith" || selectedOperatorValue === "Contains" ||
        //    selectedOperatorValue === "Eq" || selectedOperatorValue === "Geq" ||
        //    selectedOperatorValue === "In" || selectedOperatorValue === "Leq" ||
        //    selectedOperatorValue === "Lt" || selectedOperatorValue === "Neq") {
        if (selectedOperatorValue === "IsNull" || selectedOperatorValue === "IsNotNull") {
            camlOperatorValueTemplate.hide();
        }
        else {

            if (selectedOperatorValue === "In") {
                allowMultipleValues = true;
            }

            camlOperatorValueTemplate.show();

            if (IsLookupType(typeAsString) && jQuery.inArray(fieldInternalName, excludedLookupFields) == -1) {

                var lookupwebid = selectedValueObject.attr("lookupwebid");
                var lookuplist = selectedValueObject.attr("lookuplist");
                var lookupfield = selectedValueObject.attr("lookupfield");

                objTxtPropertyValue.show();
                objChkUseId.show();
                objLblUseId.show();
                objBtnSelectValue.show();

                objChkUseId.attr("onclick", "return chkUseId_onclick(this, '" + objTxtPropertyValue.attr("id") + "')");
                objBtnSelectValue.attr("onclick", "return SelectFieldValue(this, '" + fieldInternalName + "', '" + selectedOperatorValue + "', '" + allowMultipleValues + "', '" + objTxtPropertyValue.attr("id") + "', '" + typeAsString + "', 'true', '" + schemaXml + "', '" + objChkUseId.attr("id") + "', '" + lookupwebid + "', '" + lookuplist + "', '" + lookupfield + "');");
            }
            else if (typeAsString === "Choice" || typeAsString === "DateTime" || typeAsString === "User") {
                objTxtPropertyValue.show();
                objBtnSelectValue.show();

                objBtnSelectValue.attr("onclick", "return SelectFieldValue(this, '" + fieldInternalName + "', '" + selectedOperatorValue + "', '" + allowMultipleValues + "', '" + objTxtPropertyValue.attr("id") + "', '" + typeAsString + "', 'false', '" + schemaXml + "', '" + objChkUseId.attr("id") + "', '" + lookupwebid + "', '" + lookuplist + "', '" + lookupfield + "');");
            }
            else {
                objTxtPropertyValue.show();
            }
        }
    }
    else {
        camlOperatorValueTemplate.hide();
    }
}

function ddlSelectCAMLProperty_onchange(objSelectPropertyDDL) {
    var selectedFieldValue = $(objSelectPropertyDDL).val();

    var objLblSelectedFieldType = $(objSelectPropertyDDL).parent().find("label[id^='lblSelectedFieldType']");
    objLblSelectedFieldType.text("");

    var parentObject = $(objSelectPropertyDDL).parent().parent();

    var objDdlOperator = parentObject.find("select[id^='ddlOperator']");

    var objTxtPropertyValue = parentObject.find("input[id^='txtPropertyValue']");
    var objChkUseId = parentObject.find("input[id^='chkUseId']");
    var objLblUseId = parentObject.find("label[id^='lblUseId']");
    var objBtnSelectValue = parentObject.find("button[id^='btnSelectValue']");

    if (selectedFieldValue) {
        if (selectedFieldValue === "Or" || selectedFieldValue === "And") {
            objDdlOperator.hide();
            objChkUseId.hide();
            objLblUseId.hide();
            objTxtPropertyValue.hide();
            objBtnSelectValue.hide();

            if (GetChildNodeCount(parentObject) <= 1) {
                AddChildCAMLConditionNode(parentObject);
            }
            if (GetChildNodeCount(parentObject) <= 1) {
                AddChildCAMLConditionNode(parentObject);
            }
        }
        else {

            var selectedValueObject = $("#" + objSelectPropertyDDL.id + ">option:selected")
            var typeAsString = selectedValueObject.attr("typeasstring");
            objLblSelectedFieldType.text("Type: " + typeAsString);

            if (!objDdlOperator) {
                var camlOperatorTemplate = $("#camlOperatorTemplate").clone();
                var controlUniqueId = camlOperatorTemplate.attr("id") + "" + uniqueId++;
                camlOperatorTemplate.attr("id", controlUniqueId);
                camlOperatorTemplate.removeAttr("style");

                $(objSelectPropertyDDL).parent().after(camlComparisionTemplate);
            }
            else {
                objDdlOperator.parent().show();
                objDdlOperator.show();
            }

            DelesetDropDown(objDdlOperator);

            objChkUseId.hide();
            objLblUseId.hide();
            objTxtPropertyValue.hide();
            objTxtPropertyValue.val("");
            objBtnSelectValue.hide();

            if (GetSiblingNodeCount(parentObject) < 2 && IsRootNode(parentObject) === false) {
                AddSiblingCAMLConditionNode(parentObject);
            }

            RemoveChildConditionNodes();
        }
    }
    else {
        objDdlOperator.hide();
        objChkUseId.hide();
        objLblUseId.hide();
        objTxtPropertyValue.hide();
        objBtnSelectValue.hide();
    }
}

function RemoveChildConditionNodes(parentObject) {

}

function DelesetDropDown(objDdlOperator) {
    $(objDdlOperator).val('');
}

function AddChildCAMLConditionNode(parentObject) {
    var selectPropertyDropDownHtml = GenerateHtmlForSelectPropertyDDL(fieldsList)

    selectPropertyDropDownHtml = "<ul>" +
                                "<li>" +
                                    "<span>" +
                                        "<i class=\"icon-minus-sign\"></i>" +
                                        selectPropertyDropDownHtml +
                                    "</span>" +
                                "</li>" +
                            "</ul>";

    parentObject.parent().parent().after(selectPropertyDropDownHtml);
}
function AddSiblingCAMLConditionNode(parentObject) {
    var selectPropertyDropDownHtml = GenerateHtmlForSelectPropertyDDL(fieldsList)

    selectPropertyDropDownHtml = "<ul>" +
                                "<li>" +
                                    "<span>" +
                                        "<i class=\"icon-minus-sign\"></i>" +
                                        selectPropertyDropDownHtml +
                                    "</span>" +
                                "</li>" +
                            "</ul>";

    parentObject.parent().parent().parent().after(selectPropertyDropDownHtml);
}

var uniqueId = 0;

function GetCamlFieldsCheckBoxHtml(fieldsList) {
    var camlFieldsCheckBoxHtml = ""

    for (arrayIndex in fieldsList) {

        var fieldInternalName = fieldsList[arrayIndex].InternalName;
        var fieldTitle = fieldsList[arrayIndex].Title + " [" + fieldInternalName + "]";
        var fieldTypeAsString = fieldsList[arrayIndex].TypeAsString;

        var lookupAttributes = ""

        if (IsLookupType(fieldTypeAsString)) {
            fieldLookupField = fieldsList[arrayIndex].LookupField;
            fieldLookupList = fieldsList[arrayIndex].LookupList;
            fieldLookupWebId = fieldsList[arrayIndex].LookupWebId;

            lookupAttributes = "LookupField=\"" + fieldLookupField + "\" LookupList=\"" + fieldLookupList + "\" LookupWebId=\"" + fieldLookupWebId + "\"";
        }

        var otherAttributes = " CanBeDeleted=\"" + fieldsList[arrayIndex].CanBeDeleted + "\" IsHidden=\"" + fieldsList[arrayIndex].Hidden + "\" Indexed=\"" + fieldsList[arrayIndex].Indexed + "\" Required=\"" + fieldsList[arrayIndex].Required + "\" Sortable=\"" + fieldsList[arrayIndex].Sortable + "\" AllowMultipleValues=\"" + fieldsList[arrayIndex].AllowMultipleValues + "\" FromBaseType=\"" + fieldsList[arrayIndex].FromBaseType + "\"";

        camlFieldsCheckBoxHtml += "<div class=\"checkbox\"><label><input type=\"checkbox\" value=\"" + fieldInternalName + "\" TypeAsString=\"" + fieldTypeAsString + "\" " + lookupAttributes + otherAttributes + ">" + fieldTitle + "</label></div>";
    }

    return camlFieldsCheckBoxHtml;
}

function chkSelectAllCamlField_onChange(obj, args) {

    var isChecked = $(obj).is(":checked");

    if(isChecked) {
        chkSelectAllCamlField_SelectAll();
    }
    else {
        chkSelectAllCamlField_DeselectAll();
    }
}

function chkSelectAllCamlField_SelectAll() {
    var checkboxArray = $("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input");
    $.each(checkboxArray, function (index, value) {
        if ($(value).parent().parent().is(":visible")) {
            $(value).prop('checked', true);
        }
    });
}

function chkSelectAllCamlField_DeselectAll() {
    var checkboxArray = $("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input");
    $.each(checkboxArray, function (index, value) {
        $(value).prop('checked', false);
    });
}

function chkSelectAllCamlField_ShowAll() {
    $("#chkSelectAllCamlField").prop('checked', false);
    chkSelectAllCamlField_ShowFromSelector("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input");
}

function chkSelectAllCamlField_HideAll() {
    $("#chkSelectAllCamlField").prop('checked', false);
    chkSelectAllCamlField_HideFromSelector("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input");
}

function chkSelectAllCamlField_HideFromSelector(selector) {
    var checkboxArray = $(selector);
    $.each(checkboxArray, function (index, value) { 
        $(value).parent().parent().hide();
    });
}

function chkSelectAllCamlField_ShowFromSelector(selector) {
    var checkboxArray = $(selector);
    $.each(checkboxArray, function (index, value) {
        $(value).parent().parent().show();
    });
}

function chkSelectAllCamlField_ShowFields(viewFielsList) {
    var jqueryselector = viewFielsList.join(",");
    jqueryselector = "#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label " + jqueryselector + "";
    chkSelectAllCamlField_ShowFromSelector(jqueryselector);
}

function ddlSelectCamlFieldOption_onchange(obj, args) {
    chkSelectAllCamlField_DeselectAll();
    var selectedValue = $(obj).val();
    var objSelectedItem = $("#" + obj.id + ">option:selected");
    var jqueryselector = objSelectedItem.attr("jqueryselector");
    var camlFieldFilterType = objSelectedItem.attr("camlFieldFilterType");
    

    if (camlFieldFilterType === "0"){
        chkSelectAllCamlField_ShowAll();
    }
    else if (camlFieldFilterType === "1") {
        chkSelectAllCamlField_HideAll();
        chkSelectAllCamlField_ShowFromSelector("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input" + jqueryselector);
    }
    else if (camlFieldFilterType === "2") {
        chkSelectAllCamlField_HideAll();
        var listviewxml = objSelectedItem.attr('listviewxml');
        var viewFielsList = [];
        $xml = $($.parseXML(listviewxml));
        $xml.find("FieldRef").each(function () {
            viewFielsList.push('input[value=\'' + $(this).attr('Name') + '\']');
        });

        chkSelectAllCamlField_ShowFields(viewFielsList);
    }
}

function chkSelectCamlFieldOption_onChange(obj, args) {
    chkSelectAllCamlField_DeselectAll();
    var selectedValue = obj.value;

    if(selectedValue === "AllFields") {
        chkSelectAllCamlField_ShowAll();
    }
    else if(selectedValue === "ShowHidden") {
        chkSelectAllCamlField_ShowAll();
        chkSelectAllCamlField_HideFromSelector("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input[IsHidden='false']");
    }
    else if(selectedValue === "HideHidden") {
        chkSelectAllCamlField_ShowAll();
        chkSelectAllCamlField_HideFromSelector("#tabCamlQuerySelectFieldsListDiv div[class='checkbox'] label input[IsHidden='true']");
    }
}

function GetCAMLPropertyDropDown(fieldsList) {
    var selectPropertyDropDownHtml = "<select id='ddlSelectCAMLProperty' onchange='return ddlSelectCAMLProperty_onchange(this);'>" +
                                        "<option value=\"\">(Select)</option>" +
                                        "<option value=\"And\">Operator - AND</option>" +
                                        "<option value=\"Or\">Operator - OR</option>";

    for (arrayIndex in fieldsList) {
        var fieldInternalName = fieldsList[arrayIndex].InternalName;
        var fieldTitle = fieldsList[arrayIndex].Title;
        var fieldTypeAsString = fieldsList[arrayIndex].TypeAsString;
        var allowMultipleValues = fieldsList[arrayIndex].AllowMultipleValues

        var fieldLookupField = "";
        var fieldLookupList = "";
        var fieldLookupWebId = "";

        var lookupAttributes = ""

        if (IsLookupType(fieldTypeAsString)) {
            fieldLookupField = fieldsList[arrayIndex].LookupField;
            fieldLookupList = fieldsList[arrayIndex].LookupList;
            fieldLookupWebId = fieldsList[arrayIndex].LookupWebId;

            lookupAttributes = "LookupField=\"" + fieldLookupField + "\" LookupList=\"" + fieldLookupList + "\" LookupWebId=\"" + fieldLookupWebId + "\"";
        }

        var schemaXml = htmlDecode(fieldsList[arrayIndex].SchemaXml);
        if (jQuery.type(schemaXml) === "string") {
            schemaXml = schemaXml.replace(/\"/g, "&quot;");
            schemaXml = schemaXml.replace(/'/g, "&apos;");
            schemaXml = schemaXml.replace(/</g, "&lt;");
            schemaXml = schemaXml.replace(/>/g, "&gt;");
        }

        selectPropertyDropDownHtml += "<option AllowMultipleValues=\"" + allowMultipleValues + "\" TypeAsString=\"" + fieldTypeAsString + "\" value=\"" + fieldInternalName + "\" " + lookupAttributes + " SchemaXml=\"" + schemaXml + "\" >" + fieldTitle + " - [" + fieldInternalName + "]" + "</option>";
    }

    selectPropertyDropDownHtml += "</select><label id=lblSelectedFieldType></label>";

    return selectPropertyDropDownHtml;
}

function IsLookupType(fieldTypeAsString) {
    if (fieldTypeAsString === "Lookup" || fieldTypeAsString === "LookupMulti" || fieldTypeAsString.indexOf("Lookup") >= 0) {
        return true;
    }
    return false;
}

function GenerateHtmlForSelectPropertyDDL(fieldsList) {

    var tempUniqueId = uniqueId++;

    var camlComparisionTemplate = $("#camlComparisionTemplate").clone();
    var controlUniqueId = camlComparisionTemplate.attr("id") + "_" + tempUniqueId;
    camlComparisionTemplate.attr("id", controlUniqueId);
    camlComparisionTemplate.removeAttr("style");

    var camlPropertySelectionTemplate = $(camlComparisionTemplate).find("#camlPropertySelectionTemplate")

    camlPropertySelectionTemplate.html(GetCAMLPropertyDropDown(fieldsList));

    var controlUniqueId = camlPropertySelectionTemplate.attr("id") + "_" + tempUniqueId;
    camlPropertySelectionTemplate.attr("id", controlUniqueId);
    camlPropertySelectionTemplate.removeAttr("style");

    var ddlSelectCAMLProperty = $(camlComparisionTemplate).find("#ddlSelectCAMLProperty")
    var controlUniqueId = ddlSelectCAMLProperty.attr("id") + "_" + tempUniqueId;
    ddlSelectCAMLProperty.attr("id", controlUniqueId);

    var lblSelectedFieldType = $(camlComparisionTemplate).find("#lblSelectedFieldType")
    var controlUniqueId = lblSelectedFieldType.attr("id") + "_" + tempUniqueId;
    lblSelectedFieldType.attr("id", controlUniqueId);

    var camlOperatorTemplate = $(camlComparisionTemplate).find("#camlOperatorTemplate")
    var controlUniqueId = camlOperatorTemplate.attr("id") + "_" + tempUniqueId;
    camlOperatorTemplate.attr("id", controlUniqueId);

    var ddlOperator = $(camlComparisionTemplate).find("#ddlOperator")
    var controlUniqueId = ddlOperator.attr("id") + "_" + tempUniqueId;
    ddlOperator.attr("id", controlUniqueId);

    var camlOperatorValueTemplate = $(camlComparisionTemplate).find("#camlOperatorValueTemplate")
    var controlUniqueId = camlOperatorValueTemplate.attr("id") + "_" + tempUniqueId;
    camlOperatorValueTemplate.attr("id", controlUniqueId);

    var chkUseId = $(camlComparisionTemplate).find("#chkUseId")
    var controlUniqueId = chkUseId.attr("id") + "_" + tempUniqueId;
    chkUseId.attr("id", controlUniqueId);

    var lblUseId = $(camlComparisionTemplate).find("#lblUseId")
    var controlUniqueId = lblUseId.attr("id") + "_" + tempUniqueId;
    lblUseId.attr("id", controlUniqueId);

    var txtPropertyValue = $(camlComparisionTemplate).find("#txtPropertyValue")
    var controlUniqueId = txtPropertyValue.attr("id") + "_" + tempUniqueId;
    txtPropertyValue.attr("id", controlUniqueId);

    var btnSelectValue = $(camlComparisionTemplate).find("#btnSelectValue")
    var controlUniqueId = btnSelectValue.attr("id") + "_" + tempUniqueId;
    btnSelectValue.attr("id", controlUniqueId);

    selectPropertyDropDownHtml = $(camlComparisionTemplate)[0].outerHTML;

    //$(camlComparisionTemplate).find("#camlPropertySelectionTemplate").html()

    //var camlOperators = [
    //    { "Key": "", "Value": "(Select)" },
    //    { "Key": "BeginsWith", "Value": "Begins With" },
    //    { "Key": "Contains", "Value": "Contains" },
    //    { "Key": "Eq", "Value": "Equal" },
    //    { "Key": "Geq", "Value": "Greater or equal" },
    //    { "Key": "In", "Value": "In" },
    //    { "Key": "IsNull", "Value": "Is Null" },
    //    { "Key": "IsNotNull", "Value": "Is Not Null" },
    //    { "Key": "Leq", "Value": "Less or equal" },
    //    { "Key": "Lt", "Value": "Less then" },
    //    { "Key": "Neq", "Value": "not equal to" }
    //];

    //selectPropertyDropDownHtml += "<select>";

    //for (arrayIndex in camlOperators) {
    //    var camlOperatorKey = camlOperators[arrayIndex].Key;
    //    var camlOperatorValue = camlOperators[arrayIndex].Value;

    //    selectPropertyDropDownHtml += "<option value=\"" + camlOperatorKey + "\">" + camlOperatorValue + "</option>";
    //}

    //selectPropertyDropDownHtml += "</select>";

    //selectPropertyDropDownHtml += "";

    return selectPropertyDropDownHtml;
}

function PopulateFields(spListFieldsOdataUrl) {

    $.ajax({
        url: spListFieldsOdataUrl,
        type: "GET",
        headers: { "ACCEPT": "application/json;odata=verbose" },
        success: function (data, object) {
            LoadRestDataToTable(data, "divSPFieldsDetails", "bootGridSPListFields");
            fieldsList = GetSFieldsList(data);
            selectPropertyDropDownHtml = GenerateHtmlForSelectPropertyDDL(fieldsList);
            $("#tabCamlQuerySelectFieldsListDiv").html(GetCamlFieldsCheckBoxHtml(fieldsList));
            AddViewsToCamlFieldSelection();
            AddCamlTreeRootNode();
            HideProgress();
            SetCAMLTabHeight();
        },
        error: errorHandler
    });
}

function AddViewsToCamlFieldSelection() {
    var spListOdataUrl = $("#spListOdataUrl").text();
    var spListParentWebUrl = spListOdataUrl + "/Views?$select=Title,ListViewXml,Id,Hidden&$filter=Hidden eq false";
    if (spListOdataUrl.indexOf("?@target=") > -1) {
        var spOdataUrl = $("#spOdataUrl").text();
        spListParentWebUrl = StringReplaceIgnoreCase(spOdataUrl, "/Items", "/Views");
        spListParentWebUrl = StringReplaceIgnoreCase(spListParentWebUrl, "@target=", "$select=Title,ListViewXml,Id,Hidden&$filter=Hidden eq false&@target=");
        console.log(spListParentWebUrl);
    }
    RestCallWithDeferred(spListParentWebUrl).then(
            function (data, object) {
                //debugger;
                var ddlSelectCamlFieldOption = $("#ddlSelectCamlFieldOption");
                $.each(data.d.results, function (index, value) {
                    ddlSelectCamlFieldOption.append(
                        $('<option></option>').val(value.Id).html('View : ' + value.Title).attr('camlFieldFilterType', 2).attr('listviewxml', value.ListViewXml)
                    );
                });
            },
            function (XMLHttpRequest, textStatus, errorThrown) {
                errorHandler(XMLHttpRequest, textStatus, errorThrown);
            }
        );
}

function AddCamlTreeRootNode() {
    var camlRootNodeHtml = "<ul>" +
                                "<li>" +
                                    "<span>" +
                                        "<i class=\"icon-minus-sign\"></i>" +
                                        selectPropertyDropDownHtml +
                                    "</span>" +
                                "</li>" +
                            "</ul>";

    $("#jsTreeCaml").html(camlRootNodeHtml);
}

function GetSFieldsList(data) {
    var strFieldsList = "";
    for (resultIndex = 0; resultIndex < data.d.results.length; resultIndex++) {
        objSPNode = data.d.results[resultIndex];
        var fieldInternalName = objSPNode["InternalName"];
        var fieldTitle = objSPNode["Title"];
        var fieldTypeAsString = objSPNode["TypeAsString"];

        var fieldLookupField = "";
        var fieldLookupList = "";
        var fieldLookupWebId = "";

        if (IsLookupType(fieldTypeAsString)) {
            fieldLookupField = objSPNode["LookupField"];
            fieldLookupList = objSPNode["LookupList"];
            fieldLookupWebId = objSPNode["LookupWebId"];
        }
        if (strFieldsList.length > 0) {
            strFieldsList = strFieldsList + ", ";
        }

        var schemaXml = objSPNode["SchemaXml"];
        if (jQuery.type(schemaXml) === "string") {
            schemaXml = htmlEncode(schemaXml);
            schemaXml = schemaXml.replace(/(\r\n|\n|\r)/gm, "");
            schemaXml = schemaXml.replace(/\\/g, "\\\\")
            schemaXml = schemaXml.replace(/\"/g, "\\\"");

        }

        var fromBaseType = objSPNode.FromBaseType;
        if (!fromBaseType) {
            fromBaseType = false;
        }

        strFieldsList = strFieldsList + "{ \"InternalName\" : \"" + fieldInternalName + "\" , \"Title\" : \"" + fieldTitle + "\" , \"TypeAsString\" : \"" + fieldTypeAsString + "\" " +
            ", \"LookupField\" : \"" + fieldLookupField + "\" " +
            ", \"LookupList\" : \"" + fieldLookupList + "\" " +
            ", \"LookupWebId\" : \"" + fieldLookupWebId + "\" " +
            ", \"AllowMultipleValues\" : \"" + IsMultiSelect(objSPNode) + "\" " +
            ", \"SchemaXml\" : \"" + schemaXml + "\" " +
            ", \"CanBeDeleted\" : \"" + objSPNode.CanBeDeleted + "\" " +
            ", \"Hidden\" : \"" + objSPNode.Hidden + "\" " +
            ", \"Indexed\" : \"" + objSPNode.Indexed + "\" " +
            ", \"Required\" : \"" + objSPNode.Required + "\" " +
            ", \"Sortable\" : \"" + objSPNode.Sortable + "\" " +
            ", \"FromBaseType\" : \"" + fromBaseType + "\" " +
            " }";
    }

    strFieldsList = "[" + strFieldsList + "]";

    var fieldsList = JSON.parse(strFieldsList);

    return fieldsList;
}

function IsMultiSelect(objSPNode) {
    var allowMultipleValues = objSPNode["AllowMultipleValues"];

    if (allowMultipleValues) {
        return allowMultipleValues
    }
    return "false";
}

function LoadRestDataToTable(data, divId, tableId) {

    $("#" + divId).html("");

    var jsonObject = "[";
    var resultColumns = [];

    for (resultIndex = 0; resultIndex < data.d.results.length; resultIndex++) {

        objSPNode = data.d.results[resultIndex];
        var jsonRowValue = GetJsonRow(objSPNode, true);

        if (jsonRowValue.length !== "") {
            if (jsonObject.length > 1) {
                jsonObject = jsonObject + ",";
            }

            jsonObject = jsonObject + jsonRowValue;
        }

        for (propertyKey in objSPNode) {
            if (objSPNode[propertyKey] === null || typeof (objSPNode[propertyKey]) !== "object") {

                if (jQuery.inArray(propertyKey, resultColumns) === -1) {
                    resultColumns.push(propertyKey);
                }
            }
        }

    }

    jsonObject = jsonObject + "]";
    var jsonGridData = JSON.parse(jsonObject);

    LoadJsonDataToGrid(resultColumns, jsonGridData, divId, tableId);
}

function LoadJsonDataToGrid(resultColumns, jsonGridData, divId, tableId) {
    var strColumns = "";
    $.each(resultColumns, function (index, value) {
        if (strColumns.length > 0) {
            strColumns = strColumns + ", ";
        }
        strColumns = strColumns + "{ \"name\" : \"" + value + "\", \"type\": \"text\" }";
    });
    strColumns = "[ " + strColumns + " ]";
    var jsonColuns = JSON.parse(strColumns);

    var resultsHTML = "Result count: " + jsonGridData.length;

    resultsHTML = resultsHTML + "<table id=\"" + tableId + "\" class=\"table table-condensed table-hover table-striped\">";

    resultsHTML = resultsHTML + "<thead><tr>";
    for (jsonColunIndex = 0; jsonColunIndex < jsonColuns.length; jsonColunIndex++) {

        var jsonColumnName = jsonColuns[jsonColunIndex].name;

        resultsHTML = resultsHTML + "<th data-column-id=\"" + jsonColumnName + "\">" + jsonColumnName + "</th>";
    }
    resultsHTML = resultsHTML + "</tr></thead><tbody>";


    for (jsonRowIndex = 0; jsonRowIndex < jsonGridData.length; jsonRowIndex++) {
        resultsHTML = resultsHTML + "<tr>";

        var jsonRow = jsonGridData[jsonRowIndex];
        for (jsonColunIndex = 0; jsonColunIndex < jsonColuns.length; jsonColunIndex++) {
            var jsonColumnName = jsonColuns[jsonColunIndex].name;
            var columnValue = jsonRow[jsonColumnName]

            if (columnValue === undefined) {
                columnValue = "";
            }

            resultsHTML = resultsHTML + "<td>" + columnValue + "</td>";
        }

        resultsHTML = resultsHTML + "</tr>";
    }
    resultsHTML = resultsHTML + "</tbody></table>";
    $("#" + divId).html(resultsHTML);

    if (jsonGridData.length > 0) {
        //$("#" + tableId).DataTable();
        $("#" + tableId).DataTable({
            dom: 'Bfrtip',
            buttons: [
                'copyHtml5',
                'excelHtml5',
                'csvHtml5',
                'pdfHtml5'
            ],
            "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
        });
    }
}

function getDataWithCaml(oDataUrl, caml, viewFields) {

    var requestData = {
        "query":
               {
                   "__metadata": { "type": "SP.CamlQuery" },
                   "ViewXml": caml
               }
    };
    jQuery.ajax({
        url: oDataUrl,
        type: "GET",
        //method: "POST",
        data: JSON.stringify(requestData),
        headers: { "ACCEPT": "application/json;odata=verbose" },
        //headers: {
        //    "X-RequestDigest": $("#__REQUESTDIGEST").val(),
        //    "Accept": "application/json; odata=verbose",
        //    "Content-Type": "application/json; odata=verbose"
        //},
        success: function (data, object) {
            getDataWithCaml_Success(data, object);
        },
        error: getDataWithCaml_error
    });
}

function getDataWithCaml_Success(data, object) {

    LoadRestDataToTable(data, "tabCamlResultDiv", "bootGridCamResultDiv");
}

function getDataWithCaml_error(XMLHttpRequest, textStatus, errorThrown) {

    errorHandler(XMLHttpRequest, textStatus, errorThrown);
}

function chkUseId_onclick(objChkUseId, txtPropertyValueId) {
    var txtPropertyValueObj = $("#" + txtPropertyValueId);

    if ($(objChkUseId).is(":checked")) {
        var selectedIds = txtPropertyValueObj.attr("SelectedIds");
        if (selectedIds) {
            txtPropertyValueObj.val(selectedIds);
        }
        else {
            txtPropertyValueObj.val("");
        }
    }
    else {
        var selectedValues = txtPropertyValueObj.attr("SelectedValues");
        if (selectedValues) {
            txtPropertyValueObj.val(selectedValues);
        }
        else {
            txtPropertyValueObj.val("");
        }
    }
}
function SelectFieldValue(objButton, fieldInternalName, selectedOperatorValue, allowMultipleValues, txtPropertyValueId, typeAsString, isLookup, schemaXml, chkUseId, lookupWebId, lookupList, lookupField) {
    if (isLookup === 'true') {
        var txtRootWebUrl = $("#txtRootWebUrl").val();
        
        //alert(txtRootWebUrl);
        //alert(lookupWebId);
        //alert(lookupList);
        //alert(lookupField);
        lookupList = lookupList.replace("{", "");
        lookupList = lookupList.replace("}", "");

        var spListOdataUrl = txtRootWebUrl + "/_api/Web/Lists(guid'" + lookupList + "')/items";

        console.log(spListOdataUrl);

        if (isHostDataRequest) {
            spListOdataUrl = GetUrlWithAppContext(spListOdataUrl);
            spListOdataUrl = spListOdataUrl + "&";
        }
        else {
            spListOdataUrl = spListOdataUrl + "?";
        }

        console.log(spListOdataUrl);

        spListOdataUrl = spListOdataUrl + "$select=id,Title";

        console.log(spListOdataUrl);

        if (lookupField !== "Title") {
            spListOdataUrl = spListOdataUrl + "," + lookupField;
        }

        console.log(spListOdataUrl);
        
        $.ajax({
            url: spListOdataUrl,
            type: "GET",
            headers: { "ACCEPT": "application/json;odata=verbose" },
            success: function (data, object) {
                BindLookupFieldValue(data, allowMultipleValues, lookupField, txtPropertyValueId, chkUseId);
            },
            error: errorHandler
        });
    }
    else if (typeAsString === "DateTime") {
        RenderDateOptions(txtPropertyValueId);
    }
    else if (typeAsString === "User") {
        RenderUserOptions(fieldInternalName, selectedOperatorValue, txtPropertyValueId);
    }
    else {
        var choiceList = GetChoiceColumnValues(schemaXml);
        BindChoiceFieldValue(allowMultipleValues, choiceList, txtPropertyValueId);
    }
}

function RenderDateOptions(txtPropertyValueId) {
    InitDateSelection();
    ShowSelectDateValueDialog(txtPropertyValueId);
}

function chkDateSelectionType_onChange(object) {
    if (object.value === "today") {
        $('#divDateOffsetCheckBox').show();
        $('#divDateOffsetValue').hide();

        $('#divDatePicker').hide();
        $('#divIsIncludeTimeValue').hide();
    }
    else if (object.value === "specificdate") {
        $('#divDateOffsetCheckBox').hide();
        $('#divDateOffsetValue').hide();

        $('#divDatePicker').show();
        //$('#divDatePicker').datepicker({
        //});
        //$('#divDatePicker').datetimepicker({
        //    inline: true,
        //    sideBySide: true
        //});
        $('#txtDatePicker').datetimepicker({
            inline: true,
            defaultDate: new Date()
        });
        $('#divIsIncludeTimeValue').show();
    }
}

function chkAddOffset_onChange(object) {
    if ($(object).is(":checked") === true) {
        $('#divDateOffsetValue').show();
    }
    else {
        $('#divDateOffsetValue').hide();
    }
}

function InitDateSelection() {
    $.each($("input[name='dateSelectionType']:checked"), function (index, value) {
        value.checked = false;
    });

    $('#chkAddOffset').attr('checked', false);
    $('#txtDateOffset').val('');

    $('#divDateOffsetCheckBox').hide();
    $('#divDateOffsetValue').hide();

    $('#divDatePicker').hide();
    $('#divIsIncludeTimeValue').hide();

    $('#chkIsIncludeTimeValue').attr('checked', false);
}

function GetChoiceColumnValues(schemaXml) {

    var choicesList = [];
    $xml = $($.parseXML(schemaXml));
    $xml.find("CHOICE").each(function () {
        var choiceValue = $(this).text();
        choicesList.push(choiceValue);
    });

    return choicesList;
}

function BindChoiceFieldValue(allowMultipleValues, values, txtPropertyValueId) {

    var lookupValueSelectHtml = "<select id='ddlSelectLookupValue'>" +
                                    "<option value=\"\">(Select)</option>";

    if (allowMultipleValues === "true") {
        lookupValueSelectHtml = "<select id='ddlSelectLookupValue' multiple style='height: 300px; width: 500px;'>";
    }

    $.each(values, function (index, value) {
        //alert(index + ": " + value);
        lookupValueSelectHtml += "<option value=\"" + value + "\">" + value + "</option>";
    });

    lookupValueSelectHtml += "</select>";

    $("#selectFieldValueDiv").html(lookupValueSelectHtml);

    ShowSelectFieldValueDialog(txtPropertyValueId, null);
}

function BindLookupFieldValue(data, allowMultipleValues, lookupField, txtPropertyValueId, chkUseId) {

    var lookupValueSelectHtml = "<select id='ddlSelectLookupValue'>" +
                                    "<option value=\"\">(Select)</option>";

    if (allowMultipleValues === "true") {
        lookupValueSelectHtml = "<select id='ddlSelectLookupValue' multiple style='height: 300px; width: 500px;'>";
    }

    for (resultIndex = 0; resultIndex < data.d.results.length; resultIndex++) {
        objSPNode = data.d.results[resultIndex];
        var lookupFieldId = objSPNode["ID"];
        var lookupFieldValue = objSPNode[lookupField];

        lookupValueSelectHtml += "<option value=\"" + lookupFieldId + "\">" + lookupFieldValue + "</option>";
    }

    lookupValueSelectHtml += "</select>";

    $("#selectFieldValueDiv").html(lookupValueSelectHtml);

    ShowSelectFieldValueDialog(txtPropertyValueId, chkUseId);
}

function ShowSelectFieldValueDialog(txtPropertyValueId, chkUseId) {
    if (chkUseId) {
        $("#btnSelectFieldValueFromList").attr("onclick", "return bntSelectPropertyValue_onClick(this, '" + txtPropertyValueId + "', '" + chkUseId + "');", "");
    }
    else {
        $("#btnSelectFieldValueFromList").attr("onclick", "return bntSelectPropertyValue_onClick(this, '" + txtPropertyValueId + "', null);", "");
    }

    $('#selectFieldValueDialog').modal();
}

function ShowSelectDateValueDialog(txtPropertyValueId) {
    $("#btnSelectDateValue").attr("onclick", "return btnSelectDateValue_onClick(this, '" + txtPropertyValueId + "');");
    $('#selectDateValueDialog').modal();
}

function ValidateCamlInput(txtPropertyValueId) {
    var selectedDateValue = "";
    var dateSelectionTypeValue = $("input[name='dateSelectionType']:checked").val();

    if (!dateSelectionTypeValue || dateSelectionTypeValue.lenth <= 0) {
        alert("Please select date");
        return false;
    }
    else {
        if (dateSelectionTypeValue === "today") {
            if ($("#chkAddOffset").is(":checked") === true) {
                var selectedOffsetSign = $("#ddlSelectDateOffsetType option:selected").val();
                var selectedOffsetValue = $("#txtDateOffset").val();
                if (selectedOffsetValue === "") {
                    alert("Select offset value");
                    return false;
                }
                else {
                    selectedDateValue = "<Today Offset='" + selectedOffsetSign + selectedOffsetValue + "' />";
                }
            }
            else {
                selectedDateValue = "<Today />";
            }
        }
        else if (dateSelectionTypeValue === "specificdate") {
            //var selectedDate = $('#divDatePicker').data('datepicker').getDate();
            var selectedDate = $("#txtDatePicker").val();

            if (selectedDate === "") {
                alert("Select date");
                return false;
            }
            else {
                selectedDateValue = new Date(selectedDate).toISOString();
            }
        }
        else {
            alert("Invalid value for 'dateSelectionTypeValue': " + dateSelectionTypeValue);
            return false;
        }
    }

    $("#" + txtPropertyValueId).val(selectedDateValue);
    return true;
}

function btnSelectDateValue_onClick(object, txtPropertyValueId) {

    if (ValidateCamlInput(txtPropertyValueId)) {
        $('#selectDateValueDialog').modal('hide')
    }


}

function bntSelectPropertyValue_onClick(objectButton, txtPropertyValueId, chkUseId) {

    var selectedPropertyText = '';
    var selectedPropertyValue = '';
    //var selectedPropertyText = $('#ddlSelectLookupValue option:selected').text();
    //var selectedPropertyValue = $('#ddlSelectLookupValue option:selected').val();

    $.each($('#ddlSelectLookupValue option:selected'), function (key, value) {
        if (key > 0) {
            selectedPropertyText = selectedPropertyText + multipleValueSeparator;
            selectedPropertyValue = selectedPropertyValue + multipleValueSeparator;
        }
        selectedPropertyText = selectedPropertyText + value.text;
        selectedPropertyValue = selectedPropertyValue + value.value;
    });

    //alert(txtPropertyValueId);
    //alert(selectedPropertyValue);
    //alert(selectedPropertyText);

    $("#" + txtPropertyValueId).attr("SelectedIds", selectedPropertyValue)
    $("#" + txtPropertyValueId).attr("SelectedValues", selectedPropertyText)

    if (chkUseId) {
        if ($("#" + chkUseId).is(":checked")) {
            $("#" + txtPropertyValueId).val(selectedPropertyValue);
        }
        else {
            $("#" + txtPropertyValueId).val(selectedPropertyText);
        }
    }
    else {
        $("#" + txtPropertyValueId).val(selectedPropertyText);
    }

}

function btnExecuteQueryFromTxt_onClick(objBtnExecuteQueryFromTxt) {
    var viewFields = GetViewFields();
    if (viewFields.length <= "") {
        ShowValidationMessage("tabCamlQuerySelectFieldsListDiv", "Please select atleast one field");
    }
    var caml = $("#textareaCamlQuery").text();
    ShowCamlResult(caml, viewFields);
}

function ExecuteCamlQuery_onClick(objBtnExecuteQuery) {
    InitCamlResultTab("Loading results");
    var caml = ""

    var objJsTreeCaml = $("#jsTreeCaml").find("> ul");
    var childNode = objJsTreeCaml;

    var viewFields = GetViewFields();
    if (viewFields.length <= "") {
        ShowValidationMessage("tabCamlQuerySelectFieldsListDiv", "Please select atleast one field");
    }
    else {
        var viewFieldsXml = GetViewFieldsForCAML(viewFields);

        camlValidationFailed = false;
        caml = GetCaml(childNode[0]);
        if (camlValidationFailed)
        { }
        else {
            if (caml !== "") {
                caml = "<Query><Where>" + caml + "</Where></Query>";
            }

            caml = "<View" + GetScopeValue() + ">" + viewFieldsXml + caml + GetCamlRowLimit() + "</View>";
            ShowCamlResult(caml, viewFields);
        }
    }
}

function GetCamlRowLimit() {
    var txtCamlQueryRowLimitValue = "";
    if ($("#chkCamlQueryRowLimit").is(":checked") === true) {
        txtCamlQueryRowLimitValue = $('#txtCamlQueryRowLimit').val();
    }

    if (txtCamlQueryRowLimitValue) {
        if (txtCamlQueryRowLimitValue !== "") {
            txtCamlQueryRowLimitValue = "<RowLimit>" + txtCamlQueryRowLimitValue + "</RowLimit>";
        }
    }
    else {
        txtCamlQueryRowLimitValue = "";
    }
    return txtCamlQueryRowLimitValue;
}

function GetScopeValue() {
    var filesAndFolderOption = "";
    if ($("#chkFilesAndFolderOption").is(":checked") === true) {
        filesAndFolderOption = $("input[name='filesAndFolderOption']:checked").val();
    }

    if (filesAndFolderOption) {
        if (filesAndFolderOption !== "") {
            filesAndFolderOption = " Scope='" + filesAndFolderOption + "'";
        }
    }
    else {
        filesAndFolderOption = "";
    }
    return filesAndFolderOption;
}

function GetViewFieldsForCAML(viewFields) {

    var viewFieldsXml = "";

    //$.each(viewFields, function (index, value) {
    for (var viewField in viewFields) {

        //if (viewFieldsXml !== "") {
        //    viewFieldsXml += ",";
        //}

        var internalName = viewFields[viewField][0];
        viewFieldsXml += "<FieldRef Name='" + internalName + "' />";
    }
    //});

    viewFieldsXml = "<ViewFields>" + viewFieldsXml + "</ViewFields>";

    return viewFieldsXml;
}

function JoinViewFieldsByComma(viewFields) {

    var strViewFields = "";

    for (var index in viewFields) {
        var internalName = viewFields[index][0];
        if (strViewFields !== "") {
            strViewFields += ",";
        }
        strViewFields += internalName;
    }

    return strViewFields;
}
function GetViewFieldsForRest() {
    var viewFields = "";
    var expand = "";
    var selectedFields = $("#tabCamlQuerySelectFieldsListDiv").find("input:checked");

    $.each(selectedFields, function (index, value) {
        var internalName = $(value).val();

        var typeasstring = $(value).attr("typeasstring");

        if (IsLookupType(typeasstring)) {
            var lookupwebid = $(value).attr("lookupwebid");
            var lookuplist = $(value).attr("lookuplist");
            var lookupfield = $(value).attr("lookupfield");

            if (expand !== "") {
                expand += ",";
            }

            expand += internalName;

            internalName = internalName + "/" + lookupfield;
        }

        if (viewFields !== "") {
            viewFields += ",";
        }
        viewFields += internalName;
    });

    if (expand !== "") {
        viewFields += "&$expand=" + expand;
    }

    return viewFields;
}
function GetViewFields() {

    var viewFields = [];
    var expand = "";
    var selectedFields = $("#tabCamlQuerySelectFieldsListDiv div[class='checkbox']").find("input:checked");

    $.each(selectedFields, function (index, value) {
        var internalName = $(value).val();

        var typeasstring = $(value).attr("typeasstring");

        //if (IsLookupType(typeasstring))
        //{
        //    var lookupwebid = $(value).attr("lookupwebid");
        //    var lookuplist = $(value).attr("lookuplist");
        //    var lookupfield = $(value).attr("lookupfield");

        //    if (expand !== "") {
        //        expand += ",";
        //    }

        //    expand += internalName;

        //    internalName = internalName + "/" +lookupfield;
        //} 

        //viewFields += "<FieldRef Name='" +internalName + "' />";
        viewFields.push([internalName, typeasstring]);
        //if (viewFields !== "") {
        //    viewFields += ",";
        //}
        //viewFields += internalName;
    });

    //if (expand !== "") {
    //    viewFields += "&$expand=" + expand;
    //}

    //if (viewFields !== "") {
    //    viewFields = "<ViewFields>" + viewFields + "</ViewFields>";
    //}

    return viewFields;
}

function ShowCamlResult(camlQuery, viewFields) {


    var camlQuery_formatted = formatXml(camlQuery);
    $("#textareaCamlQuery").text(camlQuery_formatted);

    showTab("tabCamlResult");


    var txtRootWebUrl = $("#txtRootWebUrl").val();
    var spListTitle = $("#spListTitle").text();
    //var spListOdataUrl = $("#spListOdataUrl").text() + "/GetItems";
    var spListOdataUrl = txtRootWebUrl + "/_api/web/lists/getbytitle('" + spListTitle + "')/items";

    //var viewFields = GetViewFieldsForRest();

    //if (viewFields !== "") {
    //    spListOdataUrl = spListOdataUrl + "?$select=" + viewFields;
    //}

    //var data = getDataWithCaml(spListOdataUrl, camlQuery, viewFields);

    var viewFields = GetViewFields();
    GetListItemsFromCAML($("#txtRootWebUrl").val(), $("#spListTitle").text(), camlQuery, viewFields, $("#txtCamlQueryServerRelativeUrl").val(), $("#chkDatesInUTC").is(":checked"));
}

function GetCaml(childNode) {
    var caml = "";

    var childNodes = $(childNode).find("> li");

    var operatorValue = "";

    if (childNodes.length > 0) {

        var operatorValue = GetOperatorValue(childNodes[0])
        if (operatorValue === "") {
            caml += GetFieldCondition(childNodes[0])
        }
        else {
            caml += "<" + operatorValue + ">"
        }
    }

    var childNodes = $(childNode).find("> ul");

    if (childNodes.length > 0) {
        $.each(childNodes, function (index, value) {

            var isLeafNode = ($(value).find("> ul").length === 0);
            if (isLeafNode === false) {
                caml += GetCaml(value)
            }

            var operatorValue = GetOperatorValue(value)
            if (operatorValue !== "Or" && operatorValue !== "And") {
                caml += GetFieldCondition(value)
            }
        });
    }

    if (operatorValue !== "") {
        caml += "</" + operatorValue + ">"
    }

    return caml
}

function GetOperatorValue(operatorTreeNode) {

    var ddlSelectCAMLProperty = $(operatorTreeNode).find("select[id^='ddlSelectCAMLProperty']");
    var operatorValue = $(ddlSelectCAMLProperty).val();

    if (operatorValue !== "Or" && operatorValue !== "And") {
        return "";
    }

    return operatorValue;
}

function GetFieldCondition(conditionTreeNode) {
    var fieldCaml = "";

    var ddlSelectCAMLProperty = $(conditionTreeNode).find("select[id^='ddlSelectCAMLProperty']");
    var fieldInternalName = $(ddlSelectCAMLProperty).val();

    var objDdlOperator = $(conditionTreeNode).find("select[id^='ddlOperator']");
    var camlCondition = $(objDdlOperator).val();

    var objTxtPropertyValue = $(conditionTreeNode).find("input[id^='txtPropertyValue']");
    var fieldValue = $(objTxtPropertyValue).val();
    var userSelectionTypeValue = $(objTxtPropertyValue).attr("UserSelectionType");
    var camlQueryNode = $(objTxtPropertyValue).attr("CamlQueryNode");

    var objChkUseId = $(conditionTreeNode).find("input[id^='chkUseId']");

    if (fieldInternalName === "") {
        //alert("Field is not selected");
        return fieldCaml;
    }
    else if (camlCondition === "") {
        camlValidationFailed = true;
        //alert("Condition is not selected");
        ShowValidationMessage(objDdlOperator.attr("id"), "Condition for '" + fieldInternalName + "' not selected");
    }
    else if (fieldValue === "" && camlCondition !== "IsNull" && camlCondition !== "IsNotNull") {
        camlValidationFailed = true;
        //alert("Value for '" + fieldInternalName + "' not selected");
        ShowValidationMessage(objTxtPropertyValue.attr("id"), "Value for '" + fieldInternalName + "' not selected");
    }
    else {

        var selectedValueObject = $("#" + ddlSelectCAMLProperty[0].id + ">option:selected")

        var typeAsString = selectedValueObject.attr("typeasstring");

        var fieldCaml = "";

        if (typeAsString === "User" && fieldValue === "<UserID />") {
            typeAsString = "Integer";
        }

        if (typeAsString === "User" && userSelectionTypeValue === "membership") {
            fieldCaml = fieldValue;
        }
        else {
            var fieldRef = "<FieldRef Name='" + fieldInternalName + "' />";
            if ($(objChkUseId).is(":checked")) {
                fieldRef = "<FieldRef Name='" + fieldInternalName + "' LookupId='TRUE' />";
            }

            if (camlCondition === "In") {
                fieldCaml = "<" + camlCondition + ">" +
                             fieldRef +
                             "<Values>";


                var fieldValues = fieldValue.split(multipleValueSeparator);
                $.each(fieldValues, function (key, value) {
                    if (value !== "") {
                        fieldCaml = fieldCaml + "<Value Type='" + typeAsString + "'>" + value + "</Value>";
                    }
                });

                fieldCaml = fieldCaml + "</Values></" + camlCondition + ">";
            }
            else if (camlCondition === "IsNull" || camlCondition === "IsNotNull") {
                fieldCaml = "<" + camlCondition + ">" +
                             fieldRef +
                     "</" + camlCondition + ">";
            }
            else {
                fieldCaml = "<" + camlCondition + ">" +
                             fieldRef +
                             "<Value Type='" + typeAsString + "'>" + fieldValue + "</Value>" +
                         "</" + camlCondition + ">";
            }
        }
    }

    return fieldCaml;
}

function formatXml(xml) {
    var formatted = '';
    var reg = /(>)(<)(\/*)/g;
    xml = xml.replace(reg, '$1\r\n$2$3');
    var pad = 0;
    jQuery.each(xml.split('\r\n'), function (index, node) {
        var indent = 0;
        if (node.match(/.+<\/\w[^>]*>$/)) {
            indent = 0;
        } else if (node.match(/^<\/\w/)) {
            if (pad != 0) {
                pad -= 1;
            }
        } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
            indent = 1;
        } else {
            indent = 0;
        }

        var padding = '';
        for (var i = 0; i < pad; i++) {
            padding += '  ';
        }

        formatted += padding + node + '\n';
        pad += indent;
    });

    return formatted;
}

var spRuntimeLoaded = false;

function ShowErrorMessage(objError) {
    var errorMessage = "Oops something went wrong. Please update CAML and try again.</br></br>" +
                        "<b>Error code: </b>" + objError.get_errorCode() + "</br>" +
                        "<b>Error details: </b>" + objError.get_errorDetails() + "</br>" +
                        "<b>Error trace correlation id: </b>" + objError.get_errorTraceCorrelationId() + "</br>" +
                        "<b>Error type name: </b>" + objError.get_errorTypeName() + "</br>" +
                        "<b>Error error value: </b>" + objError.get_errorValue() + "</br>" +
                        "<b>Error message: </b>" + objError.get_message() + "</br>" +
                        "<b>Error stack trace: </b>" + objError.get_stackTrace();

    ShowModelDialogBox("Error", errorMessage);
}

function GetListItemsFromCAML(siteUrl, listTitle, xmlCamlQuery, viewFields, folderServerRelativeUrl, datesInUtc) {

    //var scriptPath = scriptbase + "SP.Runtime.js";

    if (spRuntimeLoaded) {
        console.log("Runtime already loaded...")
        var spListManager = new SPListManager(siteUrl, listTitle, xmlCamlQuery, viewFields, folderServerRelativeUrl, datesInUtc);
        var dfd = spListManager.Execute();
        dfd.done(function (spListManager) {
            spListManager.Success();
        });
        dfd.fail(function (sender, args) {
            ShowErrorMessage(args);
            if (spListManager.fail) {
                spListManager.fail(sender, args);
            }
        });
    }
    else {
        console.log("Loading runtime...")
        var scriptbase = siteUrl + "/_layouts/15/";
        $.getScript(scriptbase + "SP.Runtime.js",
            function () {
                $.getScript(scriptbase + "SP.js",
                        function () {
                            spRuntimeLoaded = true;
                            var spListManager = new SPListManager(siteUrl, listTitle, xmlCamlQuery, viewFields, folderServerRelativeUrl, datesInUtc);
                            var dfd = spListManager.Execute();
                            dfd.done(function (spListManager) {
                                spListManager.Success();
                            });
                            dfd.fail(function (sender, args) {
                                ShowErrorMessage(args);
                                if (spListManager.fail) {
                                    spListManager.fail(sender, args);
                                }
                            });
                            //ExecuteOrDelayUntilScriptLoaded(function () {
                            //RequestSP(siteUrl, listTitle, xmlCamlQuery, viewFields);
                            //}, 'sp.js');

                        }
                );
            });
    }
}

function RequestSP(siteUrl, listTitle, xmlCamlQuery, viewFields) {

    console.log(siteUrl);
    console.log(listTitle);
    var clientContext = new SP.ClientContext(siteUrl);
    var oList = clientContext.get_web().get_lists().getByTitle(listTitle);

    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(xmlCamlQuery);

    var spListItemCollection = oList.getItems(camlQuery);

    var includeFields = JoinViewFieldsByComma(viewFields);
    console.log(includeFields);
    clientContext.load(spListItemCollection, "Include(" + includeFields + ")");
}

function onQuerySucceeded(sender, args) {

    var listItemInfo = '';

    var listItemEnumerator = this.spListItemCollection.getEnumerator();//ERROR

    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();

        for (var index in this.viewFields) {
            var internalName = viewFields[index][0];
            listItemInfo += "\n" + internalName + ": " + oListItem.get_item(internalName);
        }
    }

    console.log("Success...");
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() +
        '\n' + args.get_stackTrace());
}

function btnClearQuery_onClick() {
    InitCamlBuilder();
}

function InitCamlBuilder() {
    AddCamlTreeRootNode();
    $("#textareaCamlQuery").text("");
    InitCamlResultTab("");
    InitCamlOptions();
    InitCamlQueryFields();
}

function InitCamlQueryFields() {
    var ddlSelectCamlFieldOption = $('#ddlSelectCamlFieldOption');
    if(ddlSelectCamlFieldOption && ddlSelectCamlFieldOption[0]) {
        ddlSelectCamlFieldOption[0].selectedIndex = 0;
        chkSelectAllCamlField_DeselectAll();
        chkSelectAllCamlField_ShowAll();
    }
}

function InitCamlResultTab(message) {
    $("#tabCamlResultDiv").html(message);
}

function InitCamlOptions() {
    $("#chkFilesAndFolderOption").attr('checked', false);
    //$("#chkIncludeMandatoryColumns").attr('checked', false);
    $("#chkCamlQueryRowLimit").attr('checked', false);

    $("#chkDatesInUTC").attr('checked', false);
    //$("#chkExpandUserField").attr('checked', false);
    //$("#chkIncludeAttachementUrl").attr('checked', false);
    //$("#chkIncludeAttachementVersion").attr('checked', false);

    $('#divFilesAndFolderOption').hide();
    $('#divCamlQueryRowLimit').hide();

    $('#txtCamlQueryRowLimit').val('');
    $('#txtCamlQueryServerRelativeUrl').val('');

    $.each($("input[name='filesAndFolderOption']:checked"), function (index, value) {
        value.checked = false;
    });
}

function chkFilesAndFolderOption_onChange(object) {
    if ($(object).is(":checked") === true) {
        $('#divFilesAndFolderOption').show();
    }
    else {
        $('#divFilesAndFolderOption').hide();
    }
}

function chkCamlQueryRowLimit_onChange(object) {
    if ($(object).is(":checked") === true) {
        $('#divCamlQueryRowLimit').show();
    }
    else {
        $('#divCamlQueryRowLimit').hide();
    }
}